---
title: 使用环境变量
description: 学习如何在 Astro 项目中使用环境变量。
---
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'

Astro 使用 Vite 内置支持的环境变量，你可以[使用 Vite 的任一方法](https://cn.vitejs.dev/guide/env-and-mode.html)来处理它们。

注意 虽然 _所有_ 环境变量都对服务端代码可用，但是出于安全考虑，只有以 `PUBLIC_` 前缀的环境变量才会对客户端代码可用。

```ini title=".env"
SECRET_PASSWORD=password123
PUBLIC_ANYBODY=there
```

在这个示例中，`PUBLIC_ANYBODY`（通过 `import.meta.env.PUBLIC_ANYBODY` 访问）将在客户端或服务器端代码中可用，而 `SECRET_PASSWORD`（通过 `import.meta.env.SECRET_PASSWORD` 访问）只在服务端可用。

:::caution
`.env` 文件不会加载到[配置文件](/zh-cn/guides/configuring-astro/#环境变量)中。
:::

## 默认环境变量

Astro 包括了几个开箱即用的环境变量：

- `import.meta.env.MODE`（`development` | `production`）：站点的运行模式。在运行 `astro dev` 时为 `development`，在运行 `astro build` 时为 `production`。
- `import.meta.env.PROD`（`boolean`）：当你的站点以`production`模式运行时为`true`；否则为`false`。
- `import.meta.env.DEV`（`boolean`）：当你的站点以`development`模式运行时为`true`；否则为`false`。（总是和 `import.meta.env.PROD` 相反）。
- `import.meta.env.BASE_URL`（`string`）：为站点提供服务的基础 url。它由 [`base` 配置项](/zh-cn/reference/configuration-reference/#base) 决定。
- `import.meta.env.SITE`（`string`）：特指项目中 `astro.config` 中的 [`site` 项](/zh-cn/reference/configuration-reference/#site)。
- `import.meta.env.ASSETS_PREFIX`（`string`）：如果设置了 [`build.assetsPrefix` 配置项](/zh-cn/reference/configuration-reference/#buildassetsprefix)，则指定 Astro 生成的资源链接的前缀。可以用于创建不由 Astro 处理的资源链接。

你可以将它们当作其他任意的环境变量来使用。

```ts utils.ts
const isProd = import.meta.env.PROD;
const isDev = import.meta.env.DEV;
```

## 设置环境变量

### `.env` 文件

环境变量会从项目目录中的 `.env` 文件中加载。

你也可以在文件名上附加一个模式（`production` 或 `development`），如 `.env.production` 或 `.env.development`，这使得环境变量只在该模式下生效。

只需在项目目录下创建 `.env` 文件，并在其中添加一些变量。

```ini title=".env"
# 这只有在服务器上运行时才会有效！
DB_PASSWORD="foobar"
# 这在什么地方都有效！
PUBLIC_POKEAPI="https://pokeapi.co/api/v2"
```

更多关于`.env` 文件的信息，[请参阅 Vite 文档](https://cn.vitejs.dev/guide/env-and-mode.html#env-files)。

### 使用 CLI
你也还可以在运行项目时添加环境变量：

<PackageManagerTabs>
 <Fragment slot="yarn">
    ```shell
    PUBLIC_POKEAPI=https://pokeapi.co/api/v2 yarn run dev
    ```
 </Fragment>
 <Fragment slot="npm">
    ```shell
    PUBLIC_POKEAPI=https://pokeapi.co/api/v2 npm run dev
    ```
 </Fragment>
 <Fragment slot="pnpm">
    ```shell
    PUBLIC_POKEAPI=https://pokeapi.co/api/v2 pnpm run dev
    ```
 </Fragment>
</PackageManagerTabs>

## 获取环境变量

在 Astro 中，环境变量是通过 import.meta.env 访问的，使用的是 [在 ES2020 中添加的 import.meta 功能](https://tc39.es/ecma262/2020/#prod-ImportMeta)，而不是 process.env。

例如，使用 `import.meta.env.PUBLIC_POKEAPI` 来获取 `PUBLIC_POKEAPI` 环境变量。

```js /(?<!//.*)import.meta.env.[A-Z_]+/
// 当 import.meta.env.SSR === true
const data = await db(import.meta.env.DB_PASSWORD);

// 当 import.meta.env.SSR === false
const data = fetch(`${import.meta.env.PUBLIC_POKEAPI}/pokemon/squirtle`);
```

使用 SSR 时，可以根据所使用的 SSR 适配器，在运行时访问环境变量。对于大部分适配器，可以通过 `process.env` 访问环境变量，但有一些适配器在工作时有所不同。Deno 适配器则需要使用 `Deno.env.get()`。在使用 Cloudflare 适配器时，可以参阅如何 [访问 Cloudflare 运行时](/zh-cn/guides/integrations-guide/cloudflare/#cloudflare-运行时) 以处理环境变量。Astro 会检查服务器环境中的变量，如果这些变量不存在，则会在 `.env` 文件中查找它们。

## TypeScript 智能提示

默认情况，Astro 在 `astro/client.d.ts` 中为 `import.meta.env` 提供类型定义。

当在 `.env.[mode]` 文件中定义了更多的自定义环境变量，你可能想要得到以 `PUBLIC_` 前缀的自定义环境变量的 TypeScript 智能提示。

为了实现这一点，你可以在 `src/` 中创建一个 `env.d.ts`，并配置 `ImportMetaEnv`：

```ts title="src/env.d.ts"
interface ImportMetaEnv {
  readonly DB_PASSWORD: string;
  readonly PUBLIC_POKEAPI: string;
  // 更多环境变量…
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}
```
